//
//  OMTImagePickerController.m
//  OMTImagePicker
//
//  Created by yizhaorong on 2017/11/15.
//

#import "OMTImagePickerController.h"
#import "OMTAlbumManager.h"
#import "OMTPhotoCell.h"
#import "OMTNoAlbumPermissionView.h"
#import "OMTAlbumCell.h"
#import "OMTAlbumTitleView.h"
#import "OMTPreviewViewController.h"
#import "MBProgressHUD.h"

#import "OMTAlbumHeader.h"

#import "NSString+OMTImagePicker.h"

// 图片宽
NSString *const OMTImagePickerControllerPhotoWidthKey = @"OMTImagePickerControllerPhotoWidthKey";
// 图片高度
NSString *const OMTImagePickerControllerPhotoHeightKey = @"OMTImagePickerControllerPhotoHeightKey";
// 图片文件大小
NSString *const OMTImagePickerControllerPhotoFileSizeKey = @"OMTImagePickerControllerPhotoFileSizeKey";
// 图片来源
NSString *const OMTImagePickerControllerPhotoSourceKey = @"OMTImagePickerControllerPhotoSourceKey";
// 视频时长
NSString *const OMTImagePickerControllerVideoDurationKey = @"OMTImagePickerControllerVideoDurationKey";
// URL
NSString *const OMTImagePickerControllerAssetURLKey = @"OMTImagePickerControllerAssetURLKey";
// 资源类型
NSString *const OMTImagePickerControllerAssetTypeKey = @"OMTImagePickerControllerAssetTypeKey";

// 照片重用ID
static NSString *const kPhotoCellReuseId = @"kPhotoCellReuseId";
// 相册重用ID
static NSString *const kAlbumCellReuseId = @"kAlbumCellReuseId";
// 重用Header
static NSString *const kAlbumHeaderReuseId = @"kAlbumHeaderReuseId";
// 行高
static CGFloat const kRowHeight = 60;

@interface OMTAlbumViewController : UIViewController <UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UITableViewDelegate, UITableViewDataSource, OMTNoAlbumPermissionViewDelegate, OMTPhotoCellDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
// 相册图片显示列表
@property (nonatomic, strong) UICollectionView *collectionView;
// 相册列表
@property (nonatomic, strong) UITableView *tableView;
// 动画视图
@property (nonatomic, strong) UIView *animationView;
// 未授权UI
@property (nonatomic, strong) OMTNoAlbumPermissionView *noAlbumPermissionView;
// 标题
@property (nonatomic, strong) OMTAlbumTitleView *titleView;
// 右侧标题
@property (nonatomic, strong) UIBarButtonItem *rightBarButtonItem;
// 关闭按钮
@property (strong, nonatomic) UIButton *closeButton;
// 相册
@property (nonatomic, strong) NSArray<OMTAlbum *> *albums;
// 当前选择的相册
@property (nonatomic, strong) OMTAlbum *currentAlbum;
// 拍照图标
@property (nonatomic, strong) UIImage *cameraIcon;
// 遮罩
@property (nonatomic, strong) UIControl *maskControl;
// 代理
@property (nonatomic, weak) id<OMTImagePickerControllerDelegate, UINavigationControllerDelegate> delegate;
// 相册管理器
@property (nonatomic, strong) OMTAlbumManager *albumManager;
// 相册发生了变化
@property (nonatomic, assign) BOOL assetsChanged;

- (instancetype)initWithAlbumManager:(OMTAlbumManager *)albumManager;

@end

@implementation OMTAlbumViewController

#pragma mark - Lifecycle
- (void)dealloc {
    [self unregisterNotifications];
}

- (instancetype)initWithAlbumManager:(OMTAlbumManager *)albumManager {
    if (self = [super init]) {
        self.albumManager = albumManager;
    }
    return self;
}

#pragma mark  -  View Lifecycle
- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupSubviews];
    [self setLayout];
    [self setupData];
    [self registerNotifications];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:YES];
    OMTAlbumManager *albumManager = self.albumManager;
    if (albumManager.builder.allowNotChoose) {
        [albumManager.selectedPhotos enumerateObjectsUsingBlock:^(OMTAsset *asset, NSUInteger idx, BOOL * _Nonnull stop) {
            asset.selected = NO;
        }];
        [albumManager.selectedPhotos removeAllObjects];
        if (self.assetsChanged) {
            self.assetsChanged = NO;
            for (OMTAlbum *album in self.albums) {
                [albumManager refreshAlbum:album completion:nil];
            }
        }
        [self.collectionView reloadData];
    }
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    CGRect collectionFrame = self.view.bounds;
    collectionFrame.size.height = CGRectGetHeight(collectionFrame);
    self.collectionView.frame = collectionFrame;
    
    self.noAlbumPermissionView.frame = self.view.bounds;
}

- (void)setupSubviews {
    // 初始化子视图
    self.view.backgroundColor = [UIColor whiteColor];
    self.automaticallyAdjustsScrollViewInsets = YES;
    
    OMTAlbumManager *albumManager = self.albumManager;
    UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new];
    layout.itemSize = albumManager.itemSize;
    CGFloat padding = OMTAlbumManagerPadding;
    layout.minimumLineSpacing = padding;
    layout.minimumInteritemSpacing = padding;
    layout.headerReferenceSize = CGSizeMake(0, 0);
    CGRect collectionFrame = self.view.bounds;
    
    collectionFrame.size.height = collectionFrame.size.height - CGRectGetMaxY(self.navigationController.navigationBar.frame);
    _collectionView = [[UICollectionView alloc] initWithFrame:collectionFrame collectionViewLayout:layout];
    _collectionView.contentInset = UIEdgeInsetsMake(padding, 0, padding, 0);
    [_collectionView registerClass:[OMTPhotoCell class] forCellWithReuseIdentifier:kPhotoCellReuseId];
    [_collectionView registerClass:[OMTAlbumHeader class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kAlbumHeaderReuseId];
    _collectionView.backgroundColor = [UIColor whiteColor];
    _collectionView.dataSource = self;
    _collectionView.delegate = self;
    if (@available(iOS 9.0, *)) {
        _collectionView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
    }
    if (omt_album_is_rtl_language()) {
        _collectionView.transform = CGAffineTransformMakeScale(-1, 1);
    }
    [self.view addSubview:_collectionView];
    
    _noAlbumPermissionView = [[OMTNoAlbumPermissionView alloc] initWithAlbumManager:self.albumManager];
    _noAlbumPermissionView.frame = self.view.bounds;
    _noAlbumPermissionView.delegate = self;
    _noAlbumPermissionView.hidden = YES;
    [self.view addSubview:_noAlbumPermissionView];
    
    OMTImagePickerBuilder *builder = albumManager.builder;
    
    _closeButton = [UIButton new];
    [_closeButton setImage:builder.imageWithNamed(@"omt_close_icon") forState:UIControlStateNormal];
    [_closeButton addTarget:self action:@selector(closeAction:) forControlEvents:UIControlEventTouchUpInside];
    [_closeButton sizeToFit];
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_closeButton];
    
    NSString *(^Album18N)(NSString *) = [self.albumManager.builder.localizedString copy];
    UIButton *doneButton = [UIButton new];
    [doneButton setTitle:Album18N(@"omt_album_completed") forState:UIControlStateNormal];
    [doneButton setTitleColor:builder.normalColor forState:UIControlStateNormal];
    [doneButton setTitleColor:builder.disableColor forState:UIControlStateDisabled];
    [doneButton setTitleColor:[UIColor colorWithWhite:0.85 alpha:1] forState:UIControlStateDisabled];
    [doneButton addTarget:self action:@selector(doneAction:) forControlEvents:UIControlEventTouchUpInside];
    [doneButton sizeToFit];
    _rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:doneButton];
    if (!builder.allowNotChoose) {
        _rightBarButtonItem.enabled = NO;
    }
    if (builder.showCompleteButton) {
        self.navigationItem.rightBarButtonItem = _rightBarButtonItem;
    }
    
    _titleView = [[OMTAlbumTitleView alloc] initWithAlbumManager:self.albumManager];
    _titleView.title = Album18N(@"omt_album_camera_roll");
    [_titleView addTarget:self action:@selector(titleAction) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.titleView = _titleView;

}

- (void)setLayout {
    // 设置或更新布局
    CGFloat closeW = self.closeButton.bounds.size.width;
    CGFloat doneW = self.rightBarButtonItem.customView.bounds.size.width;
    CGFloat titleMaxW = self.view.bounds.size.width - 2 * 16 - closeW - doneW;
    [self.titleView sizeToFit];
    CGFloat titleW = MIN(titleMaxW, self.titleView.bounds.size.width);
    CGFloat titleH = self.navigationController.navigationBar.bounds.size.height;
    CGFloat titleX = (self.navigationController.navigationBar.bounds.size.width - titleW) / 2;
    CGFloat titleY = (self.navigationController.navigationBar.bounds.size.height - titleH) / 2;
    CGRect titleFrame = CGRectMake(titleX, titleY, titleW, titleH);
    self.titleView.frame = titleFrame;
    self.navigationItem.titleView = self.titleView;
}

#pragma mark - Notifications

- (void)registerNotifications {
    // 注册通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(albumAssetsLoadedNotification:) name:OMTAlbumAssetsLoadedNotification object:nil];
    // 注册监听通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(becomeActiveNotification:) name:UIApplicationDidBecomeActiveNotification object:nil];
    //
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(assetsChangedNotification:) name:OMTAlbumManagerPhotoAssetsChangedNotificaton object:nil];
}
 
- (void)unregisterNotifications {
    // 注销通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - SetupData

- (void)setupData {
    // 初始化数据源
    if ([OMTAlbumManager authorized]) {
        self.collectionView.hidden = NO;
        self.noAlbumPermissionView.hidden = YES;
        OMTAlbumManager *albumManager = self.albumManager;
        __weak typeof(self) weakSelf = self;
        [albumManager allAlbumsWithCompletion:^(NSArray<OMTAlbum *> *albums, BOOL finished) {
            typeof(weakSelf) strongSelf = weakSelf;
            if (!strongSelf) return;
            
            if (!finished) return;
            strongSelf.albums = albums;
            if (!strongSelf.currentAlbum) {
                strongSelf.currentAlbum = strongSelf.albums.firstObject;
            }
            
            NSInteger index = [strongSelf.albums indexOfObject:strongSelf.currentAlbum];
            if (index != NSNotFound) {
                NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
                [strongSelf tableView:strongSelf.tableView didSelectRowAtIndexPath:indexPath];
            }
            [strongSelf.collectionView reloadData];
        }];
    } else {
        self.collectionView.hidden = YES;
        self.noAlbumPermissionView.hidden = NO;
    }
}



#pragma mark - Actions
- (void)closeAction:(UIButton *)sender {
    if ([self.delegate respondsToSelector:@selector(imagePickerControllerDidCancel:)]) {
        [self.delegate imagePickerControllerDidCancel:(OMTImagePickerController *)self.navigationController];
    } else {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
}


- (void)processAsset:(OMTAsset *)asset count:(NSInteger)count finished:(BOOL)finished image:(UIImage *)image imageData:(NSData *)imageData imageDatas:(NSMutableArray *)imageDatas images:(NSMutableArray *)images info:(NSDictionary *)info infos:(NSMutableArray *)infos picker:(OMTImagePickerController *)picker weakSelf:(OMTAlbumViewController *const __weak)weakSelf {
    OMTAlbumManager *albumManager = self.albumManager;
    BOOL isDegraded = [[info objectForKey:PHImageResultIsDegradedKey] boolValue];
    if (isDegraded) return;
    typeof(weakSelf) strongSelf = weakSelf;
    if (!strongSelf) return;
    
    if (!finished) return;
    
    [images addObject:image ? image : [NSNull new]];
    [imageDatas addObject:imageData ? imageData : [NSNull new]];
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[OMTImagePickerControllerPhotoWidthKey] = @(asset.asset.pixelWidth);
    dict[OMTImagePickerControllerPhotoHeightKey] = @(asset.asset.pixelHeight);
    dict[OMTImagePickerControllerPhotoSourceKey] = @(OMTImagePickerPhotoSourceGallery);
    dict[OMTImagePickerControllerAssetURLKey] = asset.url;
    dict[OMTImagePickerControllerVideoDurationKey] = @(asset.asset.duration);
    OMTImagePickerAssetType type = OMTImagePickerAssetTypeImage;
    switch (asset.mediaType) {
        case OMTAssetMediaTypeVideo: {
            type = OMTImagePickerAssetTypeVideo;
        } break;
            
        case OMTAssetMediaTypePhoto: {
            if (asset.isGIF) {
                type = OMTImagePickerAssetTypeGIF;
            }
        } break;
            
        default:
            break;
    }
    dict[OMTImagePickerControllerAssetTypeKey] = @(type);
    
    if (imageData) {
        dict[OMTImagePickerControllerPhotoFileSizeKey] = @(imageData.length);
    }
    [infos addObject:dict];
    
    if (count == images.count) {
        
        if (albumManager.builder.maxSelectCount > 1) {
            if ([strongSelf.delegate respondsToSelector:@selector(imagePickerController:didFinishPickingImages:imageDatas:)]) {
                [strongSelf.delegate imagePickerController:picker didFinishPickingImages:images imageDatas:imageDatas];
            }
        } else {
            if ([strongSelf.delegate respondsToSelector:@selector(imagePickerController:didFinishPickingImage:imageData:)]) {
                [strongSelf.delegate imagePickerController:picker didFinishPickingImage:images.firstObject imageData:imageDatas.firstObject];
            }
        }
        
        if (picker.imagePickerControllerDidFinishHandle) {
            picker.imagePickerControllerDidFinishHandle(picker, images, imageDatas, infos);
        }
        
        [MBProgressHUD hideHUDForView:strongSelf.view animated:YES];
    }
}

/**
 完成

 @param sender 按钮
 */
- (void)doneAction:(UIButton *)sender {
    OMTAlbumManager *albumManager = self.albumManager;
    OMTImagePickerController *picker = (OMTImagePickerController *)self.navigationController;
    // 没有选择图片
    if (albumManager.selectedPhotos.count < 1) {
        // 允许不选择图片
        if (albumManager.builder.allowNotChoose) {
            if (picker.imagePickerControllerDidFinishHandle) {
                picker.imagePickerControllerDidFinishHandle(picker, nil, nil, nil);
            }
            
            if ([self.delegate respondsToSelector:@selector(imagePickerControllerDidSkip:)]) {
                OMTImagePickerController *navigationController = (OMTImagePickerController *)self.navigationController;
                [self.delegate imagePickerControllerDidSkip:navigationController];
            }
        }
        return;
    }
    
    [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    // 选择图片数量
    NSInteger count = albumManager.selectedPhotos.count;
    __block NSMutableArray *images = [NSMutableArray arrayWithCapacity:count];
    __block NSMutableArray *imageDatas = [NSMutableArray arrayWithCapacity:count];
    __block NSMutableArray *infos = [NSMutableArray arrayWithCapacity:count];
    
    __weak typeof(self) weakSelf = self;
    for (NSInteger i = 0; i < count; i++) {
        OMTAsset *asset = albumManager.selectedPhotos[i];
        
        if (asset.mediaType == OMTAssetMediaTypeVideo) {
            PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
            options.version = PHImageRequestOptionsVersionCurrent;
            options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
            PHImageManager *manager = [PHImageManager defaultManager];
            
            
            
            [manager requestAVAssetForVideo:asset.asset options:options resultHandler:^(AVAsset *avAsset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
                
                BOOL finished = NO;
                BOOL downloadFinined = (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey]);
                if (downloadFinined && avAsset) {
                    finished = YES;
                }
                AVURLAsset *urlAsset = (AVURLAsset *)avAsset;
                NSURL *url = urlAsset.URL;
                asset.url = url;
                omt_album_dispatch_async_on_main_queue(^{
                    [weakSelf processAsset:asset count:count finished:finished image:nil imageData:nil imageDatas:imageDatas images:images info:info infos:infos picker:picker weakSelf:weakSelf];
                });
                
            }];
        } else {
            if (albumManager.builder.shouldSelectOriginImage) {
                [albumManager originalPhotoWithAsset:asset completion:^(UIImage *image, NSData *imageData, NSDictionary *info, OMTAsset *asset, BOOL finished) {
                    [weakSelf processAsset:asset count:count finished:finished image:image imageData:imageData imageDatas:imageDatas images:images info:info infos:infos picker:picker weakSelf:weakSelf];
                }];
            } else {
                [albumManager photoWithAsset:asset targetWitdh:albumManager.builder.photoWidth completion:^(UIImage *image, NSData *imageData, NSDictionary *info, BOOL isDegraded, OMTAsset *resultAsset, BOOL finished) {
                    [weakSelf processAsset:asset count:count finished:finished image:image imageData:imageData imageDatas:imageDatas images:images info:info infos:infos picker:picker weakSelf:weakSelf];
                }];
            }
        }
    }
}

/**
 点击标题事件
 */
- (void)titleAction {
    self.titleView.selected = !self.titleView.isSelected;
    
    [self.tableView reloadData];
    
    if (self.titleView.isSelected) {
        [self showAllAlbums];
    } else {
        [self hideAllAlbums];
    }
}

#pragma mark - Private


/**
 相册显示动画
 */
- (void)showAllAlbums {
    
    CGFloat animationH = MIN(kRowHeight * 6, kRowHeight * self.albums.count);
    CGRect animationFrame = self.animationView.frame;
    animationFrame.size.height = animationH + 30;
    self.animationView.frame = animationFrame;
    CGRect tableViewFrame = self.animationView.bounds;
    tableViewFrame.origin.y = 10;
    tableViewFrame.size.height = animationH + 20;
    self.tableView.frame = tableViewFrame;
    
    if (!self.animationView.superview) {
        [self.view addSubview:self.animationView];
    }
    
    CALayer *popLayer = [CALayer layer];
    popLayer = self.animationView.layer;
    popLayer.anchorPoint = CGPointMake(0.5, 0);
    
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.duration = 0.5;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    animation.values = @[@0, @1.05, @1.1, @1.04, @1.0];
    [popLayer addAnimation:animation forKey:@"scale"];
    self.maskControl.alpha = 0;
    [self.view insertSubview:self.maskControl belowSubview:self.animationView];
    [UIView animateWithDuration:0.25 animations:^{
        self.maskControl.alpha = 1;
    }];
}


/**
 相册隐藏动画
 */
- (void)hideAllAlbums {
    if (!self.animationView.superview) return;
    
    CALayer *popLayer = [CALayer layer];
    popLayer = self.animationView.layer;
    popLayer.anchorPoint = CGPointMake(0.5, 0);
    
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.duration = 0.25;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    animation.values = @[@1.0, @0];
    [popLayer addAnimation:animation forKey:@"scale"];
    [UIView animateWithDuration:0.25 animations:^{
        self.maskControl.alpha = 0;
    } completion:^(BOOL finished) {
        [self.maskControl removeFromSuperview];
        [self.animationView removeFromSuperview];
    }];
}


/**
 检测授权状态
 */
- (void)loadAlbums {
    OMTAlbumManager *albumManager = self.albumManager;
    __weak typeof(self) weakSelf = self;
    [albumManager allAlbumsWithCompletion:^(NSArray<OMTAlbum *> *albums, BOOL finished) {
        typeof(weakSelf) strongSelf = weakSelf;
        if (!strongSelf) return;
        
        if (!finished) return;
        strongSelf.albums = albums;
        
        omt_album_dispatch_async_on_main_queue(^{
            [strongSelf.collectionView reloadData];
            strongSelf.collectionView.alpha = 0;
            strongSelf.noAlbumPermissionView.alpha = 1;
            strongSelf.collectionView.hidden = NO;
            strongSelf.noAlbumPermissionView.hidden = NO;
            [UIView animateWithDuration:0.25 animations:^{
                strongSelf.collectionView.alpha = 1;
                strongSelf.noAlbumPermissionView.alpha = 0;
            } completion:^(BOOL finished) {
                strongSelf.noAlbumPermissionView.hidden = YES;
            }];
        });
    }];
    
    
}

- (OMTAlbum *)currentAlbum {
    OMTAlbum *album = self.albums.firstObject;
    for (OMTAlbum *obj in self.albums) {
        if (obj.selected) {
            album = obj;
            break;
        }
    }
    album.selected = YES;
    return album;
}


/**
 相册图片加载完成

 @param notification 通知内容
 */
- (void)albumAssetsLoadedNotification:(NSNotification *)notification {
    OMTAlbum *album = notification.object;
    if (!album || [self currentAlbum] != album) return;
    omt_album_dispatch_async_on_main_queue(^{
        [self.collectionView reloadData];
    });
}


/**
 重新激活需要刷新相册

 @param notification 通知
 */
- (void)becomeActiveNotification:(NSNotification *)notification {
    if (self.assetsChanged) {
        self.assetsChanged = NO;
        for (OMTAlbum *album in self.albums) {
            [self.albumManager refreshAlbum:album completion:nil];
        }
    }
    [self.collectionView reloadData];
}

- (void)assetsChangedNotification:(NSNotification *)notification {
    self.assetsChanged = YES;
}

- (void)takePhoto {
    NSString *(^Album18N)(NSString *) = [self.albumManager.builder.localizedString copy];
    NSString *mediaType = AVMediaTypeVideo;
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
    if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied) {
        UIAlertControllerStyle style = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? UIAlertControllerStyleAlert : UIAlertControllerStyleActionSheet;
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:Album18N(@"omt_album_camera_not_authorized_info") message:nil preferredStyle:style];
        UIAlertAction *setAction = [UIAlertAction actionWithTitle:Album18N(@"omt_album_photos_to_set_button") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        }];
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:Album18N(@"omt_album_cancel") style:UIAlertActionStyleCancel handler:nil];
        [alertController addAction:setAction];
        [alertController addAction:cancelAction];
        [self presentViewController:alertController animated:YES completion:nil];
        return;
    } else if (authStatus == AVAuthorizationStatusAuthorized || authStatus == AVAuthorizationStatusNotDetermined) {
        if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) {
            UIImagePickerController *pickrController = [[UIImagePickerController alloc] init];
            pickrController.sourceType = UIImagePickerControllerSourceTypeCamera;
            pickrController.delegate = self;
            [self presentViewController:pickrController animated:YES completion:NULL];
        } else {
            NSLog(@"模拟器中无法打开照相机,请在真机中使用");
        }
        return;
    }
    
}

- (UIImage *)rotateImageToOrientationUp:(UIImage *)originImage {
    CGSize size = originImage.size;
    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, CGRectMake(0, 0, size.width, size.height));
    [originImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

#pragma mark - Public

#pragma mark - Protocol conformance

#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    if (self.albums.count) return 1;
    return 0;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if (self.albums.count) {
        OMTAlbum *album = [self currentAlbum];
        return album.count + (self.albumManager.builder.shouldTakePhoto ? 1 : 0);
    }
    return 0;
    
}

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
    OMTAlbumHeader *headView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kAlbumHeaderReuseId forIndexPath:indexPath];
    headView.delegateController = (OMTImagePickerController *)self.navigationController;
    return headView;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    OMTPhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kPhotoCellReuseId forIndexPath:indexPath];
    NSInteger index = indexPath.row - (self.albumManager.builder.shouldTakePhoto ? 1 : 0);
    cell.albumManager = self.albumManager;
    if (indexPath.row == 0 && self.albumManager.builder.shouldTakePhoto) {
        cell.image = self.cameraIcon;
    } else {
        OMTAlbum *album = [self currentAlbum];
        OMTAsset *asset = album.assets[index];
        cell.asset = asset;
    }
    cell.delegate = self;
    return cell;
}

#pragma mark - UICollectionViewDelegateFlowLayout
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 0 && self.albumManager.builder.shouldTakePhoto) {
        [self takePhoto];
        return;
    }
    OMTPhotoCell *cell = (OMTPhotoCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
    OMTAsset *asset = cell.asset;
    if (!asset) return;
    OMTAlbumManager *albumManager = self.albumManager;
    // 不满足条件
    if (![albumManager isPhotoSelectableWithAsset:asset.asset]) {
        OMTImagePickerSelectIllegalType type = OMTImagePickerSelectIllegalTypePhoto;
        if (asset.mediaType == OMTAssetMediaTypeVideo) {
            type = OMTImagePickerSelectIllegalTypeVideo;
        }
        OMTImagePickerController *picker = (OMTImagePickerController *)self.navigationController;
        if (picker.imagePickerControllerSelectIllegalHandle) {
            picker.imagePickerControllerSelectIllegalHandle(picker, asset, type);
        }
        return;
    }
    
    self.rightBarButtonItem.enabled = YES;
    if (albumManager.builder.maxSelectCount == 1) {
        for (OMTAsset *asset in albumManager.selectedPhotos) {
            asset.selected = NO;
        }
        [albumManager.selectedPhotos removeAllObjects];
    }
    
    NSString *(^Album18N)(NSString *) = [self.albumManager.builder.localizedString copy];
    if (albumManager.builder.maxSelectCount > 1
        && albumManager.builder.maxSelectCount == albumManager.selectedPhotos.count) {
        if (!asset.selected) {
            MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
            hud.mode = MBProgressHUDModeText;
            hud.detailsLabel.text = [Album18N(@"omt_album_exceeds_maximun_limit") picker_replacePatternBy:[NSString stringWithFormat:@"%ld",albumManager.builder.maxSelectCount], nil];
            dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC);
            dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
                [MBProgressHUD hideHUDForView:self.view animated:YES];
            });
            return;
        }
    }
    
    asset.selected = !asset.isSelected;
    if (asset.selected) {
        [albumManager.selectedPhotos addObject:asset];
    } else {
        [albumManager.selectedPhotos removeObject:asset];
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:OMTAssetAssetSelectedStateChangedNotification object:asset];
    
    if (albumManager.builder.showVedio || albumManager.builder.maxSelectCount == 1) {
        [self doneAction:nil];
    }
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
    CGSize size = CGSizeZero;
    OMTAlbumManager *albumManager = self.albumManager;
    if (albumManager.builder.shouldRecordVideo) {
        CGFloat scale = CGRectGetWidth(self.view.frame) / 375.0;
        size = CGSizeMake(CGRectGetWidth(self.view.bounds), 127 * scale);
    }
    return size;
}

#pragma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    OMTAlbum *album = self.albums[indexPath.row];
    album.selected = YES;
    for (OMTAlbum *obj in self.albums) {
        if (obj != album) obj.selected = NO;
    }
    self.currentAlbum = album;
    self.titleView.title = album.name;
    [self.collectionView reloadData];
    [self hideAllAlbums];
    [self setLayout];
}

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.albums.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    OMTAlbumCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kAlbumCellReuseId];
    cell.album = self.albums[indexPath.row];
    return cell;
}

#pragma mark - OMTNoAlbumPermissionViewDelegate
- (void)noAlbumPermissionViewDidClickAllowAccess:(OMTNoAlbumPermissionView *)noAlbumPermissionView {
    OMTAuthorizationStatus status = [OMTAlbumManager authorizationStatus];
    if (status == OMTAuthorizationStatusNotDetermined) {
        __weak typeof(self) weakSelf = self;
        // 请求授权
        [OMTAlbumManager requestAuthorizationWithCompletion:^(OMTAuthorizationStatus status) {
            typeof(weakSelf) strongSelf = weakSelf;
            if (!strongSelf) return;
            
            if (status == OMTAuthorizationStatusAuthorized) {
                [strongSelf loadAlbums];
            }
        }];
    } else if (status == OMTAuthorizationStatusDenied) {
        NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        
        if([[UIApplication sharedApplication] canOpenURL:url]) {
            NSURL*url =[NSURL URLWithString:UIApplicationOpenSettingsURLString];
            [[UIApplication sharedApplication] openURL:url];
        }
    }
}

#pragma mark - OMTPhotoCellDelegate
- (void)photoCellWillPreview:(OMTPhotoCell *)cell {
    // 暂时先不开启此功能
#if 0
    OMTPreviewViewController *previewViewController = [[OMTPreviewViewController alloc] initWithAlbumManager:self.albumManager];
    [previewViewController setAsset:cell.asset placeholder:cell.image];
    [self.navigationController pushViewController:previewViewController animated:YES];
#endif
}

- (void)photoCellNeedReload:(OMTPhotoCell *)cell {
    if ([self.collectionView indexPathForCell:cell]) {
        [self.collectionView reloadData];
    }
}

#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [picker dismissViewControllerAnimated:YES completion:nil];
    NSString *type = [info objectForKey:UIImagePickerControllerMediaType];
    if ([type isEqualToString:@"public.image"]) {
        UIImage *originImage = [info objectForKey:UIImagePickerControllerOriginalImage];
        UIImage *image = [self rotateImageToOrientationUp:originImage];
        OMTImagePickerController *picker = (OMTImagePickerController *)self.navigationController;
        if (picker.imagePickerControllerDidFinishHandle) {
            NSData *imageData = UIImageJPEGRepresentation(image, 1);
            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
            dict[OMTImagePickerControllerPhotoWidthKey] = @(image.size.width);
            dict[OMTImagePickerControllerPhotoHeightKey] = @(image.size.height);
            dict[OMTImagePickerControllerPhotoSourceKey] = @(OMTImagePickerPhotoSourceCamera);
            if (imageData) {
                dict[OMTImagePickerControllerPhotoFileSizeKey] = @(imageData.length);
            }
            picker.imagePickerControllerDidFinishHandle(picker, @[image], nil, @[dict]);
        }
    }
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    [picker dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - Lazyload

- (UITableView *)tableView {
    if (!_tableView) {
        _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
        _tableView.contentInset = UIEdgeInsetsMake(10, 0, 10, 0);
        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        _tableView.rowHeight = kRowHeight;
        _tableView.dataSource = self;
        _tableView.delegate = self;
        [_tableView registerClass:[OMTAlbumCell class] forCellReuseIdentifier:kAlbumCellReuseId];
        if (@available(iOS 9.0, *)) {
            _tableView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
        }
    }
    return _tableView;
}

- (UIView *)animationView {
    if (!_animationView) {
        CGFloat width = CGRectGetWidth(self.view.frame);
//        CGFloat navH = CGRectGetMaxY(self.navigationController.navigationBar.frame);
        
        CGFloat animationX = 2;
        CGFloat animationY = 0;
        CGFloat animationW = width - 2 * animationX;
        CGFloat animationH = MIN(kRowHeight * 6, kRowHeight * self.albums.count);
        CGRect animationFrame = CGRectMake(animationX, animationY, animationW, animationH);
        _animationView = [UIView new];
        _animationView.layer.anchorPoint = CGPointMake(0.5, 0);
        _animationView.frame = animationFrame;
        
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:CGPointMake(animationW / 2, 0)];
        [path addLineToPoint:CGPointMake(animationW / 2 - 10, 10)];
        [path addLineToPoint:CGPointMake(animationW / 2 + 10, 10)];
        [path closePath];
        shapeLayer.path = path.CGPath;
        shapeLayer.fillColor = [UIColor whiteColor].CGColor;
        [_animationView.layer addSublayer:shapeLayer];
        
        self.tableView.layer.cornerRadius = 3;
        self.tableView.layer.masksToBounds = YES;
        [_animationView addSubview:self.tableView];
    }
    return _animationView;
}

- (UIImage *)cameraIcon {
    if (!_cameraIcon) {
        OMTAlbumManager *albumManager = self.albumManager;
        _cameraIcon = albumManager.builder.imageWithNamed(@"omt_camera_icon");
    }
    return _cameraIcon;
}

- (UIControl *)maskControl {
    if (!_maskControl) {
        _maskControl = [[UIControl alloc] initWithFrame:self.view.bounds];
        _maskControl.backgroundColor = [UIColor colorWithWhite:0 alpha:0.6];
        [_maskControl addTarget:self action:@selector(hideAllAlbums) forControlEvents:UIControlEventTouchUpInside];
    }
    return _maskControl;
}

#pragma mark - Custom Accessors
//自定义 setter getter

@end

#pragma mark - OMTImagePickerController

@implementation OMTImagePickerController

@synthesize delegate = _delegate;

- (void)dealloc {
    OMTAlbumManager *albumManager = self.albumManager;
    for (OMTAsset *asset in albumManager.selectedPhotos) {
        asset.selected = NO;
    }
    [albumManager.selectedPhotos removeAllObjects];
}

- (instancetype)initWithBuilder:(void (^)(OMTImagePickerBuilder *builder))builder {
    OMTAlbumManager *albumManager = [OMTAlbumManager defaultManager];
    OMTImagePickerBuilder *defaultBuilder = albumManager.builder;
    // 执行外部block
    if (builder) builder(defaultBuilder);
    // 1.设置导航栏主题
    [OMTImagePickerController setupNavBarThemeWithBuilder:defaultBuilder];
    // 2.设置导航栏按钮主题
    [OMTImagePickerController setupBarButtonItemThemeWithBuilder:defaultBuilder];
    OMTAlbumViewController *rootViewController = [[OMTAlbumViewController alloc] initWithAlbumManager:albumManager];
    if(self = [super initWithRootViewController:rootViewController]) {
        _albumManager = albumManager;
        UIImage *navbg = defaultBuilder.imageWithNamed(@"omt_nav_bg");
        [self.navigationBar setBackgroundImage:navbg forBarMetrics:UIBarMetricsDefault];
    }
    return self;
}

/**
 *  设置导航栏按钮主题
 */
+ (void)setupBarButtonItemThemeWithBuilder:(OMTImagePickerBuilder *)builder {
    UIBarButtonItem *item = [UIBarButtonItem appearance];
    
    // 设置文字属性
    NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
    textAttrs[NSForegroundColorAttributeName] = [UIColor whiteColor];
    textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:16];
    [item setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
    [item setTitleTextAttributes:textAttrs forState:UIControlStateHighlighted];
    
    NSMutableDictionary *disableTextAttrs = [NSMutableDictionary dictionary];
    disableTextAttrs[NSForegroundColorAttributeName] =  [UIColor lightGrayColor];
    [item setTitleTextAttributes:disableTextAttrs forState:UIControlStateDisabled];
}

/**
 *  设置导航栏主题
 */
+ (void)setupNavBarThemeWithBuilder:(OMTImagePickerBuilder *)builder {
    // 取出appearance对象
    UINavigationBar *navBar = [UINavigationBar appearance];
    
    // 设置标题属性
    NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
    textAttrs[NSForegroundColorAttributeName] = [UIColor whiteColor];
    textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:14];
    [navBar setTitleTextAttributes:textAttrs];
    navBar.shadowImage = [[UIImage alloc] init];
    //TODO: 设置斋月导航栏背景图
    UIImage *navbg = builder.imageWithNamed(@"omt_nav_bg");
    UIImage *stretch = [navbg stretchableImageWithLeftCapWidth:0 topCapHeight:1];
    [navBar setBackgroundImage:stretch forBarMetrics:UIBarMetricsDefault];
    
    navBar.translucent = NO;
    navBar.tintColor = [UIColor greenColor];
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if (self.viewControllers.count > 0) {
        viewController.hidesBottomBarWhenPushed = YES;
        UIButton *backButton = [[UIButton alloc] init];
        [backButton setImage:self.builder.imageWithNamed(@"omt_back_icon") forState:UIControlStateNormal];
        [backButton setImage:self.builder.imageWithNamed(@"omt_back_h_icon") forState:UIControlStateHighlighted];
        [backButton sizeToFit];
        [backButton addTarget:self action:@selector(pop) forControlEvents:UIControlEventTouchUpInside];
        viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    }
    
    [super pushViewController:viewController animated:animated];
    // 修复设置了leftBarButton后，侧滑返回无效问题
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.interactivePopGestureRecognizer.delegate = nil;
    }
}

- (void)pop {
    [self popViewControllerAnimated:YES];
}

- (UIStatusBarStyle)preferredStatusBarStyle {
    return self.builder.statusBarStyle;
}

- (void)setDelegate:(id<OMTImagePickerControllerDelegate,UINavigationControllerDelegate>)delegate {
    _delegate = delegate;
    OMTAlbumViewController *rootViewController = (OMTAlbumViewController *)self.topViewController;
    rootViewController.delegate = delegate;
}

- (id<OMTImagePickerControllerDelegate,UINavigationControllerDelegate>)delegate {
    return _delegate;
}

- (void)setBuilder:(OMTImagePickerBuilder *)builder {
    
}

- (OMTImagePickerBuilder *)builder {
    OMTAlbumManager *albumManager = self.albumManager;
    return albumManager.builder;
}

@end

